package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    AddressBookMapper addressBookMapper;
    @Autowired
    ShoppingCartMapper shoppingCartMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;

    /**
     * 用户下单
     * @param ordersSubmitDTO
     * @return
     */
    @Override
    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        // 如果地址簿为空是，下单失败，抛出异常
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if(addressBook == null){
            throw new OrderBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        //  如果购物车为空,下单失败，抛出异常
        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if(shoppingCartList == null || shoppingCartList.size() == 0){
            throw new OrderBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        // 1、向订单表插入一条订单数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, order);
        order.setUserId(userId);
        order.setOrderTime(LocalDateTime.now());
        order.setNumber(String.valueOf(System.currentTimeMillis()) + String.valueOf(userId));
        order.setPhone(addressBook.getPhone());
        order.setConsignee(addressBook.getConsignee());
        order.setPayStatus(Orders.UN_PAID);
        order.setStatus(Orders.PENDING_PAYMENT);

        orderMapper.insert(order);

        // 2、向订单详情表插入多条购物车数据
        List<OrderDetail> orderDetailList = new ArrayList<OrderDetail>();
        Long orderId = order.getId();
        System.out.println("orderId : " + orderId);

        for(ShoppingCart shopping: shoppingCartList){
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shopping, orderDetail);
            orderDetail.setOrderId(orderId);
            orderDetailList.add(orderDetail);
        }

        orderDetailMapper.insertBatch(orderDetailList);

        // 3、清空购物车数据
        shoppingCartMapper.cleanByUserId(userId);

        // 4、封装VO返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder().
                id(order.getId()).
                orderNumber(order.getNumber()).
                orderAmount(order.getAmount()).
                orderTime(order.getOrderTime()).
                build();
        return orderSubmitVO;
    }

    /**
     * 分页获取历史订单
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult getHistory(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 分页查询
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());

        // 查询历史订单信息
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        Page<Orders> pages = orderMapper.pageQuery(ordersPageQueryDTO);

        // 查询历史订单细节信息
        List<OrderVO> orderVOList = addOrderDetailToOrderVO(pages);

        return new PageResult(pages.getTotal(), orderVOList);
    }

    /**
     * 将订单细节加入到OrderVO中
     * @param pages
     * @return
     */
    private List<OrderVO>addOrderDetailToOrderVO(Page<Orders> pages){
        List<OrderVO> orderVOList = new ArrayList<>();
        if(pages != null && pages.getTotal() > 0){
            for(Orders order : pages){
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(order, orderVO);
                List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(order.getId());
                orderVO.setOrderDetailList(orderDetailList);

                // 设置订单菜品名称
                String orderDish = createOrderDishes(orderDetailList);
                orderVO.setOrderDishes(orderDish);

                orderVOList.add(orderVO);
            }
        }
        return orderVOList;
    }

    /**
     * 生成orderDishes
     * @param orderDetailList
     * @return
     */
    private String createOrderDishes(List<OrderDetail> orderDetailList){
        List<String> list = new ArrayList<>();
        for(OrderDetail orderDetail : orderDetailList){
            String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber() + ";";
            list.add(orderDish);
        }
        return String.join(",", list);
    }

    /**
     * 订单明细
     * @param id
     * @return
     */
    @Override
    public OrderVO details(Long id) {
        OrderVO orderVO = new OrderVO();

        // 查询订单数据
        Orders order = orderMapper.getById(id);
        BeanUtils.copyProperties(order, orderVO);

        // 查询订单详情
        List<OrderDetail> orderDetail = orderDetailMapper.getByOrderId(order.getId());
        orderVO.setOrderDetailList(orderDetail);

        return orderVO;
    }

    /**
     * 取消订单
     * @param id
     */
    @Override
    // 订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 7退款
    public void cancel(Long id) {
        Orders order = orderMapper.getById(id);
        if(order == null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        Integer status = order.getStatus();

        //- 商家已接单状态下，用户取消订单需电话沟通商家
        //- 派送中状态下，用户取消订单需电话沟通商家
        //- 如果在待接单状态下取消订单，需要给用户退款
        if(status > 2){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //- 待支付和待接单状态下，用户可直接取消订单

        // 待接单的情况下， 需要退款处理
        if(status == Orders.TO_BE_CONFIRMED){
            // 调用微信支付中的退款功能
            /*
             weChatPayUtil.refund(
                    ordersDB.getNumber(), //商户订单号
                    ordersDB.getNumber(), //商户退款单号
                    new BigDecimal(0.01),//退款金额，单位 元
                    new BigDecimal(0.01));//原订单金额
             */

            // 将支付状态设置为 退款
            order.setPayStatus(Orders.REFUND);
        }

        //- 取消订单后需要将订单状态修改为“已取消”  设置订单取消时间 设置订单取消原因
        order.setStatus(Orders.CANCELLED);
        order.setCancelReason("用户取消");
        order.setCancelTime(LocalDateTime.now());

        orderMapper.update(order);
    }

    /**
     * 再来一单
     * @param id
     */
    @Override
    public void repetition(Long id) {
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(id);
        Long userId = BaseContext.getCurrentId();

        // 讲订单详情复制到购物车数据中
        List<ShoppingCart> shoppingCartList = new ArrayList<>();

        for(OrderDetail orderDetail : orderDetails){
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setUserId(userId);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCartList.add(shoppingCart);
        }

        shoppingCartMapper.insertBatch(shoppingCartList);
    }


    /**
     * 分类搜索
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<Orders> pages = orderMapper.pageQuery(ordersPageQueryDTO);

        List<OrderVO> orderVOList = addOrderDetailToOrderVO(pages);
        return new PageResult(pages.getTotal(), orderVOList);
    }

    @Override
    public OrderStatisticsVO statistics() {
        Integer toBeConfirmed = orderMapper.countByStatus(Orders.TO_BE_CONFIRMED);
        Integer confirmed = orderMapper.countByStatus(Orders.CONFIRMED);
        Integer deliveryInProgress = orderMapper.countByStatus(Orders.DELIVERY_IN_PROGRESS);

        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
        return orderStatisticsVO;
    }

    @Override
    public void comfirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersConfirmDTO, order);
        order.setStatus(Orders.CONFIRMED);
        orderMapper.update(order);
    }

    @Override
    public void reject(OrdersRejectionDTO ordersRejectionDTO) {
        Orders order = orderMapper.getById(ordersRejectionDTO.getId());
        if(order.getStatus() == Orders.TO_BE_CONFIRMED){
            // 如果处于已支付状态，需要退款
            if(order.getPayStatus() == Orders.PAID){
                /*
                    //用户已支付，需要退款
                    String refund = weChatPayUtil.refund(
                    ordersDB.getNumber(),
                    ordersDB.getNumber(),
                    new BigDecimal(0.01),
                    new BigDecimal(0.01));
                    log.info("申请退款：{}", refund);
                 */
            }
            order.setRejectionReason(ordersRejectionDTO.getRejectionReason());
            order.setStatus(Orders.CANCELLED);
            order.setCancelTime(LocalDateTime.now());
            orderMapper.update(order);
        }
        else{
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
    }

    @Override
    public void adminCancel(OrdersCancelDTO ordersCancelDTO) {
        Orders order = orderMapper.getById(ordersCancelDTO.getId());
        // 如果处于已支付状态，需要退款
        if(order.getPayStatus() == Orders.PAID){
            /*
                //用户已支付，需要退款
                String refund = weChatPayUtil.refund(
                ordersDB.getNumber(),
                ordersDB.getNumber(),
                new BigDecimal(0.01),
                new BigDecimal(0.01));
                log.info("申请退款：{}", refund);
             */
        }
        order.setStatus(Orders.CANCELLED);
        order.setCancelTime(LocalDateTime.now());
        order.setCancelReason(ordersCancelDTO.getCancelReason());
        orderMapper.update(order);
    }

    @Override
    public void delivery(Long id) {
        Orders order = orderMapper.getById(id);
        if(order != null && order.getStatus() == Orders.CONFIRMED){
            order.setStatus(Orders.DELIVERY_IN_PROGRESS);
            orderMapper.update(order);
        }
        else{
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
    }

    @Override
    public void complete(Long id) {
        Orders order = orderMapper.getById(id);
        if(order != null && order.getStatus() == Orders.DELIVERY_IN_PROGRESS){
            order.setStatus(Orders.COMPLETED);
            orderMapper.update(order);
        }
        else{
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
    }

}
